package com.trailwalker.javafx.core.application;

import com.trailwalker.JavaUtils.log.LogUtils;
import com.trailwalker.javafx.core.activity.Activity;
import com.trailwalker.javafx.core.activity.ActivityContext;
import com.trailwalker.javafx.core.entity.Intent;
import com.trailwalker.javafx.utils.screen.ScreenUtils;
import com.trailwalker.javafx.utils.stage.StageUtils;
import com.trailwalker.javafx.utils.system.ApplicationUtils;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Trailwalker
 * @create 2021-08-31 11:18
 * @des
 */
public abstract class JavaFxApplication extends Application {

    private static final String TAG = JavaFxApplication.class.getSimpleName();

    private Stage mPrimaryStage;

    private ScreenUtils mScreenUtils;
    private List<Activity> mActivityList;
    private AnchorPane mApContainerView;
    private JavaFxApplication mApplication;
    private Scene mScene;

    /**
     * JavaFX-Launcher线程
     *
     * @throws Exception
     */
    @Override
    public void init() throws Exception {
        super.init();
        LogUtils.log(TAG, "application init work at Thread:" + Thread.currentThread().getName());
        mApplication = this;
        mActivityList = new ArrayList<>();
        onApplicationInit();
    }

    /**
     * JavaFX ui 线程
     *
     * @param primaryStage
     * @throws Exception
     */
    @Override
    public void start(Stage primaryStage) throws Exception {
        LogUtils.log(TAG, "application start work at Thread:" + Thread.currentThread().getName());

        mPrimaryStage = primaryStage;
        mScreenUtils = ScreenUtils.getInstance();
        double screenWidth = mScreenUtils.getWidth();
        double screenHeight = mScreenUtils.getHeight();

        //StageUtils.setTitle(mPrimaryStage, "MediaPlayer");
        //StageUtils.addIcon(mPrimaryStage, new Image(ResourceUtils.getImage(mApplication, "avatar.jpg")));
        StageUtils.setResizable(mPrimaryStage, true);
        double defaultStageHeight = screenHeight / 4 * 3;
        mPrimaryStage.setHeight(defaultStageHeight);
        mPrimaryStage.setWidth(defaultStageHeight / 2 * 3);
        mApContainerView = new AnchorPane();
        mScene = new Scene(mApContainerView);
//        int theme = PreferencesManager.getInstance().getInt("theme", 1);
//        if (theme == 0) {
//            mScene.getStylesheets().add(ResourceUtils.getCss(mApplication, "lightTheme.css"));
//        } else {
//            mScene.getStylesheets().add(ResourceUtils.getCss(mApplication, "darkTheme.css"));
//        }
        mPrimaryStage.setScene(mScene);
        StageUtils.initStyle(mPrimaryStage, StageStyle.TRANSPARENT);
        onApplicationStart();
        startMainActivity();
        StageUtils.show(mPrimaryStage);
    }

    /**
     * 打开首页
     */
    private void startMainActivity() {
        Intent intent = initMainActivity();
        startActivity(intent);
    }

    /**
     * JavaFX ui 线程
     *
     * @throws Exception
     */
    @Override
    public void stop() throws Exception {
        super.stop();
        LogUtils.log(TAG, "application stop work at Thread:" + Thread.currentThread().getName());
        clearActivityList();
        onApplicationStop();
        System.exit(0);
    }

    public void startActivity(Intent intent) {
        Class<? extends Activity> activityClass = intent.getActivityClass();
        String clzName = activityClass.getName();
        try {
            Class<?> clzActivity = Class.forName(clzName);
            try {
                Constructor<?> activityConstructor = clzActivity.getConstructor();
                try {
                    Activity activity = (Activity) activityConstructor.newInstance();
                    mActivityList.add(activity);
                    activity.setIntent(intent);
                    activity.setContainerView(mApContainerView);
                    activity.setApplication(mApplication);
                    activity.onCreate();
                } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
                    e.printStackTrace();
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public void finish(Activity activity) {
        if (mActivityList.size() > 1) {
            boolean isNeedRestart = false;
            if (mActivityList.get(mActivityList.size() - 1).equals(activity)) {
                isNeedRestart = true;
            }
            activity.onDestroy();
            mActivityList.remove(activity);
            if (isNeedRestart) {
                ActivityContext topActivity = mActivityList.get(mActivityList.size() - 1);
                topActivity.onRestart();
            }
        } else {
            ApplicationUtils.exit();
        }
    }

    protected void reload() {
        clearActivityList();
        startMainActivity();
    }

    private void clearActivityList() {
        for (int i = mActivityList.size() - 1; i >= 0; i--) {
            Activity activity = mActivityList.get(i);
            activity.onDestroy();
            mActivityList.remove(activity);
        }
    }

    public JavaFxApplication getApplication() {
        return mApplication;
    }

    public Scene getScene() {
        return mScene;
    }

    public Stage getStage() {
        return mPrimaryStage;
    }

    public void onBackPressed() {
        ActivityContext activity = mActivityList.get(mActivityList.size() - 1);
        activity.onBackPressed();
    }

    public abstract void onApplicationInit();

    public abstract void onApplicationStart();

    public abstract void onApplicationStop();

    public abstract Intent initMainActivity();
}
